using System;

namespace Neo.MetaModel
{
    [Serializable]
	public class EntityAttribute
	{
		//--------------------------------------------------------------------------------------
		//	fields and constructor
		//--------------------------------------------------------------------------------------

		private String		propertyName;
		private Type		propertyType;
		private String		propertyAttributes; /* custom attributes in the .NET sense */

		private String		columnName;
		private String		columnType;
		private String		size;
        private String      description = "";

		private Boolean		isPkColumn;
		private Boolean		allowsNull;
		private Boolean		isRequired;
		private Boolean		isHidden;
        private Boolean     isIdentityColumn;
        private Boolean     isSQLTextColumn;
        private Boolean     isReadOnly;
        private Boolean     display;
        private Boolean		allowChanges;

		private String		defaultValue; 
		private String 		inputValidator;
        private Boolean     constraint;
        
        /*
		public EntityAttribute(Entity anEntity)
		{
		}
        */

		//--------------------------------------------------------------------------------------
		//	public attributes
		//--------------------------------------------------------------------------------------

        public bool IsSQLTextColumn
        {
            set { isSQLTextColumn = value; }
            get { return isSQLTextColumn; }
        }

        public string InputValidator
        {
            set { inputValidator = value; }
            get { return inputValidator; }
        }
        
        public bool IsIdentityColumn
        {
            set { isIdentityColumn = value; }
            get { return isIdentityColumn; }
        }

        public string Description
        {
            set { description = value; }
            get { return description; }
        }

		public string PropertyName
		{
			set { propertyName = value; }
			get { return propertyName; }
		}

		public Type PropertyType
		{
			set { propertyType = value; }
			get { return propertyType; }
		}

		public String PropertyAttributes
		{
			set { propertyAttributes = value; }
			get { return propertyAttributes; }
		}
		
		public String[] PropertyAttributeArray
		{
			get 
			{ 
				if (String.IsNullOrEmpty(propertyAttributes))
					return new string[0];
				return propertyAttributes.Split(';'); 
			}
		}

		public string ColumnName
		{
			set { columnName = value; }
			get { return columnName; }
		}

		public string ColumnType
		{
			set { columnType = value; }
			get { return columnType; }
		}

		public string Size
		{
			set { size = value; }
			get { return size; }
		}

		public bool AllowsNull
		{
			set { allowsNull = value; }
			get { return allowsNull; }
		}

		public bool IsPkColumn
		{
			set { isPkColumn = value; }
			get { return isPkColumn; }
		}

		public bool IsHidden
		{
			set { isHidden = value; }
			get { return isHidden; }
		}

		public bool IsRequired
		{
			set { isRequired = value; }
			get { return isRequired; }
		}

        public bool IsReadOnly
        {
            set { isReadOnly = value; }
            get { return isReadOnly; }
        }
        
        public bool Display
        {
            set { display = value; }
            get { return display; }
        }
        
        public bool AllowChanges
        {
            set { allowChanges = value; }
            get { return allowChanges; }
        }

		public string DefaultValue 
		{
			get { return defaultValue; }
			set { defaultValue = value; }
		}

        public Boolean Constraint 
		{
			get { return constraint; }
			set { constraint = value; }
		}
         
		//--------------------------------------------------------------------------------------
		//	compatibility
		//--------------------------------------------------------------------------------------

		public string DotNetName
		{
			get { return PropertyName; }
		}

		public string DotNetType
		{
			get { return PropertyType.FullName; }
		}


		//--------------------------------------------------------------------------------------
		//  helper methods
		//--------------------------------------------------------------------------------------

		public void SetDefaultColumnType(Type dataType)
		{
			if(dataType.Equals(typeof(Boolean)))
				columnType = "BIT";
			else if(dataType.Equals(typeof(Int16)))
				columnType =  "SMALLINT";
			else if(dataType.Equals(typeof(Int32)))
				columnType =  "INTEGER";
			else if(dataType.Equals(typeof(Int64)))
				columnType =  "BIGINT";
			else if(dataType.Equals(typeof(Double)))
				columnType =  "DOUBLE";
			else if(dataType.Equals(typeof(Decimal)))
				columnType =  "DECIMAL";
			else if(dataType.Equals(typeof(String)))
				columnType =  "VARCHAR";
			else if(dataType.Equals(typeof(DateTime)))
				columnType =  "DATETIME";
			else if(dataType.Equals(typeof(byte[])))
				columnType =  "BINARY";
			else if(dataType.Equals(typeof(Guid)))
				columnType =  "UNIQUEIDENTIFIER";
			else
				throw new ArgumentException("Data type " + dataType + " not supported.");
		}

        public override string ToString()
        {
            if (String.IsNullOrEmpty(PropertyName))
            {
                return base.ToString();
            }
            return PropertyName;
        }

        public string ToXml()
        {
            string column = "\t\t" + @"<column name=""#name#"" javaName=""#javaName#"" type=""#type#"" required=""#required#"" ";

            column = column.Replace("#name#", this.ColumnName);
            column = column.Replace("#javaName#", String.IsNullOrEmpty(this.PropertyName) ? this.ColumnName : this.PropertyName);
            column = column.Replace("#type#", this.ColumnType);
            column = column.Replace("#required#", this.IsRequired.ToString().ToLower());
            if (this.IsHidden)
                column += @"hidden=""true"" ";
            if (this.ColumnType.Equals("VARCHAR") || this.ColumnType.Equals("CHAR"))
                column += "size=\"" + this.Size + "\" ";
            if (this.IsPkColumn)
                column += @"primaryKey=""true"" ";
            if (this.IsIdentityColumn)
                column += @"autoIncrement=""true"" ";
            column += @"description="""" ";
            column += @"/>" + Environment.NewLine;
            return column;
        }
	}
}
